#include <linux/module.h>

#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
#include <linux/platform_device.h>
#include <linux/of.h>

#include "led_opr.h"
#include "leddrv.h"
#include "led_resource.h"

static int g_ledpins[100];
static int g_ledcont;


//构造  led_operations 结构体

static  int led_init (int which)  //初始化LED， which 表示那个LED
{
    printk("%s %s grop: %d pin :%d",__FILE__,__FUNCTION__,GROUP(g_ledpins[which]),PIN(g_ledpins[which]));
    switch (GROUP(g_ledpins[which]))
    {
         case 0:
        {
            printk("init pin of group 0 ...\n");
            break;
        }
        case 1:
        {
            printk("init pin of group 1 ...\n");
            break;
        }
        case 2:
        {
            printk("init pin of group 2 ...\n");
            break;
        }
        case 3:
        {
            printk("init pin of group 3 ...\n");
            break;
        }
    }
    return 0;
}
static  int led_ctl  (int  which, char status)//控制LED   which 那个LED   status 1  亮  0 灭
{
        //printk("%s %s lin: %d led :%d status %s",__FILE__,__FUNCTION__,__LINE__,which,status ? "on":"off");
        printk("%s %s grop: %d pin :%d status %s",__FILE__,__FUNCTION__,GROUP(g_ledpins[which]),PIN(g_ledpins[which]),status ? "on":"off");
         switch (GROUP(g_ledpins[which]))
    {
         case 0:
        {
            printk("set pin of group 0 ...\n");
            break;
        }
        case 1:
        {
            printk("set pin of group 1 ...\n");
            break;
        }
        case 2:
        {
            printk("set pin of group 2 ...\n");
            break;
        }
        case 3:
        {
            printk("set pin of group 3 ...\n");
            break;
        }
    }
        return 0;
}
static struct led_operations led_board_RK3399_opr = 
{
    .init = led_init,
    .ctl = led_ctl,
};


//资源接口，给顶层  driver 调用 
struct led_operations *get_board_led_oper()
{
    return  &led_board_RK3399_opr;
}



//构造一个 platform_driver
static int my_leds_probe(struct platform_device *pdev)
{
    int err= 0;
    struct device_node * np;
    int led_pin ;
    np = pdev->dev.of_node;
    if(!np )
    return  -1;
    /*
static inline int of_property_read_u32(const struct device_node *np,
				       const char *propname,
				       u32 *out_value)
    */
    err = of_property_read_u32(np,"pin",&led_pin);//读取 设备树中pin 的值
    g_ledpins[g_ledcont] = led_pin;    //保存pin属性 ，操作pin的时候需要用到
    class_create_device(g_ledcont);  //创建设备节点
    g_ledcont++;
    return 0;
}

static int my_leds_remove(struct platform_device* pdev)
{
    int err = 0;
    struct device_node* np;
    int led_pin;
    int i ;
    np = pdev->dev.of_node;
    if(!np )
    return -1;
    err = of_property_read_u32(np,"pin",&led_pin);
     for(i =0;i< g_ledcont ;i++)//找到pin 对应的节点进行删除
     {
         if(g_ledpins[i] == led_pin)
         {
             g_ledpins[i]  = -1;
             class_distroy_device(i);
             break;
         }
     }

     //判定是否全部被移除
     for(i = 0; i < g_ledcont;i++)
     {
         if(g_ledpins[i] != -1)
         break;
     }
     if(i  == g_ledcont)
     g_ledcont = 0;

     return 0;
}

static const struct of_device_id myled_table[] = {
	{ .compatible = "rk3399,my_leds" },
	{ },
};
static struct platform_driver my_leds_driver = {
	.driver	= {
		.name		= "my_ledS",
		.of_match_table = myled_table,
	},
	.probe		= my_leds_probe,
    .remove   =  my_leds_remove,
};



// 谁来注册驱动程序？ 通过入口函数  在执行insmod 命令的时候会去调用 这个入口函数
static int __init chip_led_gpio_init(void)
{
    //注册平台设备
    int err;
    err  = platform_driver_register(&my_leds_driver);
    register_led_operations(&led_board_RK3399_opr);//向上层driver 注册具体的led操作函数
        return  0;
}
//卸载驱动程序时，出口函数会调用 unreagister_chardev函数 来卸载当前驱动程序

static void __exit chip_led_gpio_exit(void)
{
    //卸载平台设备
    platform_driver_unregister(&my_leds_driver);
}


//提供设备信息，自动创建设备节点, class_create  device_create
module_init(chip_led_gpio_init);  //申明入口
module_exit(chip_led_gpio_exit);//申明出口

MODULE_LICENSE("GPL");






